#include "bsp_aht21_driver.h"

// #define AHT_CLK_ENABLE __HAL_RCC_GPIOB_CLK_ENABLE()
#define IIC_INTERFACE  bsp_aht21_driver->psiic_interface
#define OS_DELAY_MS    bsp_aht21_driver->psyield_interface->os_delay_ms    

//读状态字
uint8_t AHT_Read_Status(bsp_aht21_driver_t *bsp_aht21_driver)
{
	uint8_t Byte_first;	

    #if 0
    IICStart(&AHT_bus);
    IICSendByte(&AHT_bus,0x71);                 //0x71设备地址读,0x70设备地址写
    IICWaitAck(&AHT_bus);
    Byte_first = IICReceiveByte(&AHT_bus);
    IICSendNotAck(&AHT_bus);
    IICStop(&AHT_bus);
    #else

    IIC_INTERFACE->pfiic_start(NULL);    
    IIC_INTERFACE->pfiic_send_byte(NULL, 0x71);   //0x71设备地址读,0x70设备地址写
	IIC_INTERFACE->pfiic_wait_ack(NULL);
    Byte_first = IIC_INTERFACE->pfiic_receive_byte(NULL);
    IIC_INTERFACE->pfiic_send_no_ack(NULL);
    IIC_INTERFACE->pfiic_stop(NULL);
	return Byte_first;

    #endif
}

#if 0
//检查 AHT21 是否启用了校准
uint8_t AHT_Read_Cal_Enable(void)  //check cal enable bit 
{
	uint8_t val = 0;//ret = 0,
 
  val = AHT_Read_Status();
  if((val & 0x68)==0x08)  //check NOR mode 
		return 1;
  else  
		return 0;
}

void AHT_Reset(void)//AHT21 send 0xBA reset call
{
	IICStart(&AHT_bus);
	IICSendByte(&AHT_bus,0x70);
	IICWaitAck(&AHT_bus);
	IICSendByte(&AHT_bus,0xBA);
	IICWaitAck(&AHT_bus);
	IICStop(&AHT_bus);
}
#endif

int8_t aht_init(bsp_aht21_driver_t *bsp_aht21_driver)
{
    #if 0
    //AHT_CLK_ENABLE;     //打开GPIOB时钟,打开时钟放在freeRTOS.c执行
    //IICInit(&AHT_bus);
    //delay_ms(40);
    #else
    IIC_INTERFACE->pfiic_init(NULL);
	OS_DELAY_MS(40);
	#endif
	
	if(AHT_Read_Status(bsp_aht21_driver)&&0x08!=0x08)
	{
        #if 0
		IICStart(&AHT_bus);
		IICSendByte(&AHT_bus,0x70);
		IICWaitAck(&AHT_bus);
		IICSendByte(&AHT_bus,0xBE);
		IICWaitAck(&AHT_bus);
		IICSendByte(&AHT_bus,0x08);
		IICWaitAck(&AHT_bus);
		IICSendByte(&AHT_bus,0x00);
		IICWaitAck(&AHT_bus);
		IICStop(&AHT_bus);
		delay_ms(10);
        #else
        IIC_INTERFACE->pfiic_start     (NULL);
        IIC_INTERFACE->pfiic_send_byte (NULL, 0x70);
        IIC_INTERFACE->pfiic_wait_ack  (NULL);
        IIC_INTERFACE->pfiic_send_byte (NULL, 0xBE);
        IIC_INTERFACE->pfiic_wait_ack  (NULL);
        IIC_INTERFACE->pfiic_send_byte (NULL, 0x08);
        IIC_INTERFACE->pfiic_wait_ack  (NULL);
        IIC_INTERFACE->pfiic_send_byte (NULL, 0x00);
        IIC_INTERFACE->pfiic_wait_ack  (NULL);
        IIC_INTERFACE->pfiic_stop      (NULL);
        OS_DELAY_MS(10);
        #endif
	}
	//AHT_Reset();
	//read_id();   //读取id成功
	
	return 0;
}
int8_t aht_deinit(bsp_aht21_driver_t *bsp_aht21_driver)
{
    return 0;
}
int8_t read_id(bsp_aht21_driver_t *bsp_aht21_driver)
{
    return 0;
}
int8_t aht_read(bsp_aht21_driver_t *bsp_aht21_driver, float *humi, float *temp)
{
	uint8_t cnt=5;
	uint8_t  Byte_1th=0;
	uint8_t  Byte_2th=0;
	uint8_t  Byte_3th=0;
	uint8_t  Byte_4th=0;
	uint8_t  Byte_5th=0;
	uint8_t  Byte_6th=0;
	uint32_t RetuData = 0;
	
    #if 0
	//读温度命令0XAC 0X33 0X00
	IICStart(&AHT_bus);
	IICSendByte(&AHT_bus,0x70);
	IICWaitAck(&AHT_bus);
	IICSendByte(&AHT_bus,0xAC);
	IICWaitAck(&AHT_bus);
	IICSendByte(&AHT_bus,0x33);
	IICWaitAck(&AHT_bus);
	IICSendByte(&AHT_bus,0x00);
	IICWaitAck(&AHT_bus);
	IICStop(&AHT_bus);	
	
	//数据手册要求延时80ms
	delay_ms(80);

    //aht21状态是否空闲(温湿度采集完成)
	while(AHT_Read_Status()&0x80==0x80 && cnt) 
	{
		delay_ms(5);
		cnt--;
		AHT_Read_Status();
	}
	if(!cnt)
	{return 1;}

    //前两个半字节事湿度数据,后两个半数据是温度数据,最后是CRC校验
	IICStart(&AHT_bus);
	IICSendByte(&AHT_bus,0x71);
	IICWaitAck(&AHT_bus);
	Byte_1th = IICReceiveByte(&AHT_bus);
	IICSendAck(&AHT_bus);
	Byte_2th = IICReceiveByte(&AHT_bus);
	IICSendAck(&AHT_bus);
	Byte_3th = IICReceiveByte(&AHT_bus);
	IICSendAck(&AHT_bus);
	Byte_4th = IICReceiveByte(&AHT_bus);
	IICSendAck(&AHT_bus);
	Byte_5th = IICReceiveByte(&AHT_bus);
	IICSendAck(&AHT_bus);
	Byte_6th = IICReceiveByte(&AHT_bus);
	IICSendNotAck(&AHT_bus);
	IICStop(&AHT_bus);
    #else
    //读温度命令0XAC 0X33 0X00
    IIC_INTERFACE->pfiic_start(NULL);
    IIC_INTERFACE->pfiic_send_byte(NULL, 0x70);
    IIC_INTERFACE->pfiic_wait_ack(NULL);
    IIC_INTERFACE->pfiic_send_byte(NULL, 0xAC);
    IIC_INTERFACE->pfiic_wait_ack(NULL);
    IIC_INTERFACE->pfiic_send_byte(NULL, 0x33);
    IIC_INTERFACE->pfiic_wait_ack(NULL);
    IIC_INTERFACE->pfiic_send_byte(NULL, 0x00);
    IIC_INTERFACE->pfiic_wait_ack(NULL);
    IIC_INTERFACE->pfiic_stop(NULL);
    //数据手册要求延时80ms
    OS_DELAY_MS(80);

    //aht21状态是否空闲(温湿度采集完成)
    while(AHT_Read_Status(bsp_aht21_driver)&0x80==0x80 && cnt) 
	{
		OS_DELAY_MS(5);
		cnt--;
		AHT_Read_Status(bsp_aht21_driver);
	}
	if(!cnt)
	{return 1;}

    //前两个半字节事湿度数据,后两个半数据是温度数据,最后是CRC校验
    IIC_INTERFACE->pfiic_start(NULL);
    IIC_INTERFACE->pfiic_send_byte(NULL, 0x71);
    IIC_INTERFACE->pfiic_wait_ack(NULL);   
    Byte_1th = IIC_INTERFACE->pfiic_receive_byte(NULL);
    IIC_INTERFACE->pfiic_send_ack(NULL);
    Byte_2th = IIC_INTERFACE->pfiic_receive_byte(NULL);
    IIC_INTERFACE->pfiic_send_ack(NULL);
	Byte_3th = IIC_INTERFACE->pfiic_receive_byte(NULL);
	IIC_INTERFACE->pfiic_send_ack(NULL);
	Byte_4th = IIC_INTERFACE->pfiic_receive_byte(NULL);
	IIC_INTERFACE->pfiic_send_ack(NULL);
	Byte_5th = IIC_INTERFACE->pfiic_receive_byte(NULL);
	IIC_INTERFACE->pfiic_send_ack(NULL);
	Byte_6th = IIC_INTERFACE->pfiic_receive_byte(NULL);
	IIC_INTERFACE->pfiic_send_no_ack(NULL);
	IIC_INTERFACE->pfiic_stop(NULL);
    #endif
	
	//计算相对湿度
	RetuData = (RetuData|Byte_2th)<<8;
	RetuData = (RetuData|Byte_3th)<<8;
	RetuData = (RetuData|Byte_4th);
	RetuData =RetuData >>4;
	*humi = (RetuData * 1000 >> 20);
	*humi /= 10;
	
	//计算温度
	RetuData = 0;
	RetuData = (RetuData|(Byte_4th&0x0f))<<8;
	RetuData = (RetuData|Byte_5th)<<8;
	RetuData = (RetuData|Byte_6th);
	RetuData = RetuData&0xfffff;
	*temp = ((RetuData * 2000 >> 20)- 500);
	*temp /= 10;
	
	return 0;
}

int8_t sleep(bsp_aht21_driver_t *bsp_aht21_driver)
{
    return 0;
}
int8_t wakeup(bsp_aht21_driver_t *bsp_aht21_driver)
{
    return 0;
}
//构造函数
int8_t  inst_driver( bsp_aht21_driver_t        *bsp_aht21_driver, 
                      iic_driver_interface_t    *iic_interface,
                      yield_interface_t         *psyield_interface,
                      irq_interface_t           *psirq_interface)
{
    //1.参数判空

	//2.组装结构体
	bsp_aht21_driver->id              = 0;   //初始化id
	bsp_aht21_driver->psiic_interface = iic_interface;
	bsp_aht21_driver->psirq_interface = psirq_interface;
	bsp_aht21_driver->psyield_interface = psyield_interface;
	
    //3.赋值本层函数接口
    bsp_aht21_driver->pfaht_init   = aht_init;
    bsp_aht21_driver->pfaht_deinit = aht_deinit;
    bsp_aht21_driver->pfread_id    = read_id;
    bsp_aht21_driver->pfaht_read   = aht_read;
    bsp_aht21_driver->pfsleep      = sleep;
    bsp_aht21_driver->pfwakeup     = wakeup;

    //4.调用aht_init
    aht_init(bsp_aht21_driver);

    return 0;
}
